from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from .models import Post, Comment, Like
from .forms import PostForm
from user.models import User
from django.http import Http404, HttpResponseNotAllowed, JsonResponse
from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from django.views.decorators.http import require_POST
from django.db.models import F, ExpressionWrapper, FloatField
from django.db.models.functions import Now, Extract
from datetime import datetime
from django.views.decorators.csrf import csrf_exempt
from django.core.files.storage import default_storage
import uuid

def list_posts(request):
    posts = Post.objects.filter(
        draft=False,
        author__is_active=True
    ).annotate(
        # 计算帖子发布至今的天数
        days_since_published=Extract(
            Now() - F('published_at'),
            'day'
        ),
        # 计算综合得分：时间权重 * 浏览量权重
        # 时间权重：1 / (天数 + 1)，避免除以0
        # 浏览量权重：ln(浏览量 + 1)，使用对数避免浏览量差异过大
        score=ExpressionWrapper(
            1.0 / (F('days_since_published') + 1) * 
            (F('view_times') + 1),
            output_field=FloatField()
        )
    ).order_by('-score')
    return render(request, 'journal/post_list.html', {'posts': posts})

def list_someones_posts(request, user_id):
    author = get_object_or_404(User, id=user_id)
    
    if not author.is_active:
        raise Http404()
    
    if request.user.id == author.id:
        posts = Post.objects.filter(author=author)
    else:
        posts = Post.objects.filter(
            author=author,
            draft=False,
            private=False
        )
    
    posts = posts.order_by('-published_at')
    return render(request, 'journal/someones_post_list.html', {
        'posts': posts,
        'author': author
    })

def post_detail(request, id):
    post = get_object_or_404(Post, id=id)
    if post.draft and post.author != request.user:
        raise Http404()
    
    # 获取文章的所有评论
    displayed_comments = post.comments.filter(is_displayed=True).order_by('-created_at')
    not_displayed_comments = post.comments.filter(is_displayed=False).order_by('-created_at')
    user_not_displayed_comments = Comment.objects.filter(
        post=post,
        author=request.user,
        is_displayed=False
    ) if request.user.is_authenticated else None
    i_liked = post.likes.filter(user=request.user).exists() if request.user.is_authenticated else False
    
    return render(request, 'journal/post_detail.html', {
        'post': post,
        'displayed_comments': displayed_comments,
        'not_displayed_comments': not_displayed_comments,
        "user_not_displayed_comments": user_not_displayed_comments,
        'i_liked': i_liked
    })


@login_required
def write_post(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            
            # 只在发布时修改状态
            action = request.POST.get('action')
            if action == 'publish':
                post.draft = False
                post.published_at = timezone.now()
            
            post.save()
            return redirect('post_detail', id=post.id)
    else:
        form = PostForm()
    
    return render(request, 'journal/write_post.html', {'form': form})

@login_required
def modify_post(request, id):
    # 获取文章并检查权限
    post = get_object_or_404(Post, id=id)
    if post.author != request.user:
        raise Http404()
    
    context = {}
    
    if request.method == 'POST':
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            post = form.save(commit=False)
            
            # 只在发布时修改状态
            action = request.POST.get('action')
            if action == 'publish':
                post.draft = False
                if post.published_at is None:
                    post.published_at = timezone.now()
            
            post.save()
            return redirect('post_detail', id=post.id)
    else:
        form = PostForm(instance=post)
    context['is_published'] = post.published_at is not None
    context['form'] = form
    return render(request, 'journal/write_post.html', context)

@login_required
def delete_post(request, id):
    # 获取文章并检查权限
    post = get_object_or_404(Post, id=id)
    if post.author != request.user:
        raise Http404()
    
    # 只允许 POST 方法
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    
    # 删除文章
    post.delete()
    return redirect('post_list')

@login_required
def write_comment(request, id):
    # 获取对应的文章
    post = get_object_or_404(Post, id=id)
    
    # 只接受 POST 请求
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    
    # 创建新评论
    content = request.POST.get('content')
    if content:
        comment = Comment.objects.create(
            post=post,
            author=request.user,
            content=content
        )
        
    # 重定向向回文章详情页
    return redirect('post_detail', id=id)

@login_required
def delete_comment(request, id):
    # 获取评论并检查是否存在
    comment = get_object_or_404(Comment, id=id)
    
    # 检查权限：只有评论作者或者文章作者可以删除评论
    if request.user != comment.author and request.user != comment.post.author:
        raise Http404()
    
    # 只允许 POST 方法
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    
    # 删除评论
    comment.delete()
    
    # 重定向回文章详情页
    return redirect('post_detail', id=comment.post.id)

@login_required
def make_comment_display(request, id):
    # 获取评论并检查是否存在
    comment = get_object_or_404(Comment, id=id)
    
    # 检查权限：只有文章作者可以公开评论
    if request.user != comment.post.author:
        raise Http404()
    
    # 只允许 POST 方法
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    
    # 将评论设为公开/不公开显示
    comment.is_displayed = bool(request.POST['display'])
    comment.save()
    
    # 返回用户之前的页面，如果没有则返回文章详情页
    referer = request.META.get('HTTP_REFERER')
    if referer:
        return redirect(referer)
    return redirect('post_detail', id=comment.post.id)

@login_required
def like_post(request):
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    
    post_id = request.POST.get('post_id')
    post = get_object_or_404(Post, id=post_id)
    
    # 检查是否已经点赞
    content_type = ContentType.objects.get_for_model(Post)
    like, created = Like.objects.get_or_create(
        user=request.user,
        content_type=content_type,
        object_id=post.id
    )
    
    return redirect('post_detail', id=post.id)

@login_required
def cancel_like_post(request):
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])
    
    post_id = request.POST.get('post_id')
    post = get_object_or_404(Post, id=post_id)
    
    # 删除点赞记录
    content_type = ContentType.objects.get_for_model(Post)
    Like.objects.filter(
        user=request.user,
        content_type=content_type,
        object_id=post.id
    ).delete()
    
    return redirect('post_detail', id=post.id)

def list_my_post_comments(request):
    pass

@require_POST
def increment_view_count(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    post.view_times += 1
    post.save(update_fields=['view_times'])
    return JsonResponse({'status': 'success', 'view_times': post.view_times})

@csrf_exempt
def upload_image(request):
    if request.method != 'POST':
        return JsonResponse({'success': 0})
    
    image = request.FILES.get('image')
    if not image:
        return JsonResponse({'success': 0})
    
    # 生成唯一的文件名
    file_extension = image.name.split('.')[-1]
    filename = f'editor_images/{uuid.uuid4()}.{file_extension}'
    
    # 保存文件
    path = default_storage.save(filename, image)
    file_url = default_storage.url(path)
    
    return JsonResponse({
        'success': 1,
        'file': {
            'url': file_url
        }
    })